#include "Thread.h"
#include "Pointer.h"
#include "../Collections/List.h"

#ifdef _MSC_VER
#else
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h> 
#include <sys/time.h>
#define SIGRESUME SIGUSR2  
#define SIGSUSPEND SIGUSR1 
#endif

namespace zl
{
#ifdef _MSC_VER
	using namespace threading_internal;
	using namespace collections;

	namespace threading_internal
	{
		struct WaitableData
		{
			HANDLE			handle;

			WaitableData(HANDLE _handle)
				:handle(_handle)
			{
			}
		};
	}

	WaitableObject::WaitableObject()
		:waitableData(0)
	{
	}

	void WaitableObject::SetData(threading_internal::WaitableData* data)
	{
		waitableData = data;
	}

	bool WaitableObject::IsCreated()
	{
		return waitableData != 0;
	}

	bool WaitableObject::Wait()
	{
		return WaitForTime(INFINITE);
	}

	bool WaitableObject::WaitForTime(zint ms)
	{
		if (IsCreated())
		{
			if (WaitForSingleObject(waitableData->handle, (DWORD)ms) == WAIT_OBJECT_0)
			{
				return true;
			}
		}
		return false;
	}

	bool WaitableObject::WaitAll(WaitableObject** objects, zint count)
	{
		Array<HANDLE> handles(count);
		for (zint i = 0; i<count; i++)
		{
			handles[i] = objects[i]->waitableData->handle;
		}
		DWORD result = WaitForMultipleObjects((DWORD)count, &handles[0], TRUE, INFINITE);
		return result == WAIT_OBJECT_0 || result == WAIT_ABANDONED_0;

	}

	bool WaitableObject::WaitAllForTime(WaitableObject** objects, zint count, zint ms)
	{
		Array<HANDLE> handles(count);
		for (zint i = 0; i<count; i++)
		{
			handles[i] = objects[i]->waitableData->handle;
		}
		DWORD result = WaitForMultipleObjects((DWORD)count, &handles[0], TRUE, (DWORD)ms);
		return result == WAIT_OBJECT_0 || result == WAIT_ABANDONED_0;
	}

	zint WaitableObject::WaitAny(WaitableObject** objects, zint count, bool* abandoned)
	{
		Array<HANDLE> handles(count);
		for (zint i = 0; i<count; i++)
		{
			handles[i] = objects[i]->waitableData->handle;
		}
		DWORD result = WaitForMultipleObjects((DWORD)count, &handles[0], FALSE, INFINITE);
		if (WAIT_OBJECT_0 <= result && result<WAIT_OBJECT_0 + count)
		{
			*abandoned = false;
			return result - WAIT_OBJECT_0;
		}
		else if (WAIT_ABANDONED_0 <= result && result<WAIT_ABANDONED_0 + count)
		{
			*abandoned = true;
			return result - WAIT_ABANDONED_0;
		}
		else
		{
			return -1;
		}
	}

	zint WaitableObject::WaitAnyForTime(WaitableObject** objects, zint count, zint ms, bool* abandoned)
	{
		Array<HANDLE> handles(count);
		for (zint i = 0; i<count; i++)
		{
			handles[i] = objects[i]->waitableData->handle;
		}
		DWORD result = WaitForMultipleObjects((DWORD)count, &handles[0], FALSE, (DWORD)ms);
		if (WAIT_OBJECT_0 <= result && result<WAIT_OBJECT_0 + count)
		{
			*abandoned = false;
			return result - WAIT_OBJECT_0;
		}
		else if (WAIT_ABANDONED_0 <= result && result<WAIT_ABANDONED_0 + count)
		{
			*abandoned = true;
			return result - WAIT_ABANDONED_0;
		}
		else
		{
			return -1;
		}
	}

	namespace threading_internal
	{
		struct ThreadData : public WaitableData
		{
			DWORD						id;

			ThreadData()
				:WaitableData(NULL)
			{
				id = -1;
			}
		};

		class ProceduredThread : public Thread
		{
		private:
			Thread::ThreadProcedure		procedure;
			void*						argument;
			bool						deleteAfterStopped;

		protected:
			void Run()
			{
				procedure(this, argument);
				if (deleteAfterStopped)
				{
					delete this;
				}
			}
		public:
			ProceduredThread(Thread::ThreadProcedure _procedure, void* _argument, bool _deleteAfterStopped)
				:procedure(_procedure)
				, argument(_argument)
				, deleteAfterStopped(_deleteAfterStopped)
			{
			}
		};

		class LambdaThread : public Thread
		{
		private:
			std::function<void()>    	procedure;
			bool						deleteAfterStopped;

		protected:
			void Run()
			{
				procedure();
				if (deleteAfterStopped)
				{
					delete this;
				}
			}
		public:
			LambdaThread(const std::function<void()>& _procedure, bool _deleteAfterStopped)
				:procedure(_procedure)
				, deleteAfterStopped(_deleteAfterStopped)
			{
			}
		};
	}

	void InternalThreadProc(Thread* thread)
	{
		thread->Run();
		thread->threadState = Thread::Stopped;
	}

	DWORD WINAPI InternalThreadProcWrapper(LPVOID lpParameter)
	{
		InternalThreadProc((Thread*)lpParameter);
		return 0;
	}

	Thread::Thread()
	{
		internalData = new ThreadData;
		internalData->handle = CreateThread(NULL, 0, InternalThreadProcWrapper, this, CREATE_SUSPENDED, &internalData->id);
		threadState = Thread::NotStarted;
		SetData(internalData);
	}

	Thread::~Thread()
	{
		Stop();
		CloseHandle(internalData->handle);
		delete internalData;
	}

	Thread* Thread::CreateAndStart(ThreadProcedure procedure, void* argument, bool deleteAfterStopped)
	{
		if (procedure)
		{
			Thread* thread = new ProceduredThread(procedure, argument, deleteAfterStopped);
			if (thread->Start())
			{
				return thread;
			}
			else
			{
				delete thread;
			}
		}
		return 0;
	}

	Thread* Thread::CreateAndStart(const std::function<void()>& procedure, bool deleteAfterStopped)
	{
		Thread* thread = new LambdaThread(procedure, deleteAfterStopped);
		if (thread->Start())
		{
			return thread;
		}
		else
		{
			delete thread;
		}
		return 0;
	}

	void Thread::Sleep(zint ms)
	{
		::Sleep((DWORD)ms);
	}

	zint Thread::GetCPUCount()
	{
		SYSTEM_INFO info;
		GetSystemInfo(&info);
		return info.dwNumberOfProcessors;
	}

	zint Thread::GetCurrentThreadId()
	{
		return (zint)::GetCurrentThreadId();
	}

	bool Thread::Start()
	{
		if (threadState == Thread::NotStarted && internalData->handle != NULL)
		{
			if (ResumeThread(internalData->handle) != -1)
			{
				threadState = Thread::Running;
				return true;
			}
		}
		return false;
	}

	bool Thread::Pause()
	{
		if (threadState == Thread::Running)
		{
			if (SuspendThread(internalData->handle) != -1)
			{
				threadState = Thread::Paused;
				return true;
			}
		}
		return false;
	}

	bool Thread::Resume()
	{
		if (threadState == Thread::Paused)
		{
			if (ResumeThread(internalData->handle) != -1)
			{
				threadState = Thread::Running;
				return true;
			}
		}
		return false;
	}

	bool Thread::Stop()
	{
		if (internalData->handle != NULL)
		{
			Pause();
			threadState = Thread::Stopped;
			return true;
		}
		return false;
	}

	Thread::ThreadState Thread::GetState()
	{
		return threadState;
	}

	void Thread::SetCPU(zint index)
	{
		SetThreadAffinityMask(internalData->handle, (1 << index));
	}

	/***********************************************************************
	Mutex
	***********************************************************************/

	namespace threading_internal
	{
		struct MutexData : public WaitableData
		{
			MutexData(HANDLE _handle)
			:WaitableData(_handle)
			{
			}
		};
	}

	Mutex::Mutex()
		:internalData(0)
	{
	}

	Mutex::~Mutex()
	{
		if (internalData)
		{
			CloseHandle(internalData->handle);
			delete internalData;
		}
	}

	bool Mutex::Create(bool owned, const std::wstring& name)
	{
		if (IsCreated())return false;
		BOOL aOwned = owned ? TRUE : FALSE;
		LPCTSTR aName = name == L"" ? NULL : name.c_str();
		HANDLE handle = CreateMutex(NULL, aOwned, aName);
		if (handle)
		{
			internalData = new MutexData(handle);
			SetData(internalData);
		}
		return IsCreated();
	}

	bool Mutex::Open(bool inheritable, const std::wstring& name)
	{
		if (IsCreated())return false;
		BOOL aInteritable = inheritable ? TRUE : FALSE;
		HANDLE handle = OpenMutex(SYNCHRONIZE, aInteritable, name.c_str());
		if (handle)
		{
			internalData = new MutexData(handle);
			SetData(internalData);
		}
		return IsCreated();
	}

	bool Mutex::Release()
	{
		if (IsCreated())
		{
			return ReleaseMutex(internalData->handle) != 0;
		}
		return false;
	}

	/***********************************************************************
	Semaphore
	***********************************************************************/

	namespace threading_internal
	{
		struct SemaphoreData : public WaitableData
		{
			SemaphoreData(HANDLE _handle)
			:WaitableData(_handle)
			{
			}
		};
	}

	Semaphore::Semaphore()
		:internalData(0)
	{
	}

	Semaphore::~Semaphore()
	{
		if (internalData)
		{
			CloseHandle(internalData->handle);
			delete internalData;
		}
	}

	bool Semaphore::Create(zint initialCount, zint maxCount, const std::wstring& name)
	{
		if (IsCreated())return false;
		LONG aInitial = (LONG)initialCount;
		LONG aMax = (LONG)maxCount;
		LPCTSTR aName = name == L"" ? NULL : name.c_str();
		HANDLE handle = CreateSemaphore(NULL, aInitial, aMax, aName);
		if (handle)
		{
			internalData = new SemaphoreData(handle);
			SetData(internalData);
		}
		return IsCreated();
	}

	bool Semaphore::Open(bool inheritable, const std::wstring& name)
	{
		if (IsCreated())return false;
		BOOL aInteritable = inheritable ? TRUE : FALSE;
		HANDLE handle = OpenSemaphore(SYNCHRONIZE, aInteritable, name.c_str());
		if (handle)
		{
			internalData = new SemaphoreData(handle);
			SetData(internalData);
		}
		return IsCreated();
	}

	bool Semaphore::Release()
	{
		if (IsCreated())
		{
			return Release(1) != -1;
		}
		return false;
	}

	zint Semaphore::Release(zint count)
	{
		if (IsCreated())
		{
			LONG previous = -1;
			if (ReleaseSemaphore(internalData->handle, (LONG)count, &previous) != 0)
			{
				return (zint)previous;
			}
		}
		return -1;
	}

	/***********************************************************************
	EventObject
	***********************************************************************/

	namespace threading_internal
	{
		struct EventData : public WaitableData
		{
			EventData(HANDLE _handle)
			:WaitableData(_handle)
			{
			}
		};
	}

	EventObject::EventObject()
		:internalData(0)
	{
	}

	EventObject::~EventObject()
	{
		if (internalData)
		{
			CloseHandle(internalData->handle);
			delete internalData;
		}
	}

	bool EventObject::CreateAutoUnsignal(bool signaled, const std::wstring& name)
	{
		if (IsCreated())return false;
		BOOL aSignaled = signaled ? TRUE : FALSE;
		LPCTSTR aName = name == L"" ? NULL : name.c_str();
		HANDLE handle = CreateEvent(NULL, FALSE, aSignaled, aName);
		if (handle)
		{
			internalData = new EventData(handle);
			SetData(internalData);
		}
		return IsCreated();
	}

	bool EventObject::CreateManualUnsignal(bool signaled, const std::wstring& name)
	{
		if (IsCreated())return false;
		BOOL aSignaled = signaled ? TRUE : FALSE;
		LPCTSTR aName = name == L"" ? NULL : name.c_str();
		HANDLE handle = CreateEvent(NULL, TRUE, aSignaled, aName);
		if (handle)
		{
			internalData = new EventData(handle);
			SetData(internalData);
		}
		return IsCreated();
	}

	bool EventObject::Open(bool inheritable, const std::wstring& name)
	{
		if (IsCreated())return false;
		BOOL aInteritable = inheritable ? TRUE : FALSE;
		HANDLE handle = OpenEvent(SYNCHRONIZE, aInteritable, name.c_str());
		if (handle)
		{
			internalData = new EventData(handle);
			SetData(internalData);
		}
		return IsCreated();
	}

	bool EventObject::Signal()
	{
		if (IsCreated())
		{
			return SetEvent(internalData->handle) != 0;
		}
		return false;
	}

	bool EventObject::Unsignal()
	{
		if (IsCreated())
		{
			return ResetEvent(internalData->handle) != 0;
		}
		return false;
	}

	/***********************************************************************
	ThreadPoolLite
	***********************************************************************/

	struct ThreadPoolQueueProcArgument
	{
		void(*proc)(void*);
		void* argument;
	};

	DWORD WINAPI ThreadPoolQueueProc(void* argument)
	{
		Ptr<ThreadPoolQueueProcArgument> proc = (ThreadPoolQueueProcArgument*)argument;
		proc->proc(proc->argument);
		return 0;
	}

	DWORD WINAPI ThreadPoolQueueFunc(void* argument)
	{
		Ptr<std::function<void()>> proc = (std::function<void()>*)argument;
		(*proc.Obj())();
		return 0;
	}

	ThreadPoolLite::ThreadPoolLite()
	{
	}

	ThreadPoolLite::~ThreadPoolLite()
	{
	}

	bool ThreadPoolLite::Queue(void(*proc)(void*), void* argument)
	{
		ThreadPoolQueueProcArgument* p = new ThreadPoolQueueProcArgument;
		p->proc = proc;
		p->argument = argument;
		if (QueueUserWorkItem(&ThreadPoolQueueProc, p, WT_EXECUTEDEFAULT))
		{
			return true;
		}
		else
		{
			delete p;
			return false;
		}
	}

	bool ThreadPoolLite::Queue(const std::function<void()>& proc)
	{
		std::function<void()>* p = new std::function<void()>(proc);
		if (QueueUserWorkItem(&ThreadPoolQueueFunc, p, WT_EXECUTEDEFAULT))
		{
			return true;
		}
		else
		{
			delete p;
			return false;
		}
	}

	/***********************************************************************
	CriticalSection
	***********************************************************************/

	namespace threading_internal
	{
		struct CriticalSectionData
		{
			CRITICAL_SECTION		criticalSection;
		};
	}

	CriticalSection::Scope::Scope(CriticalSection& _criticalSection)
		:criticalSection(&_criticalSection)
	{
		criticalSection->Enter();
	}

	CriticalSection::Scope::~Scope()
	{
		criticalSection->Leave();
	}

	CriticalSection::CriticalSection()
	{
		internalData = new CriticalSectionData;
		InitializeCriticalSection(&internalData->criticalSection);
	}

	CriticalSection::~CriticalSection()
	{
		DeleteCriticalSection(&internalData->criticalSection);
		delete internalData;
	}

	bool CriticalSection::TryEnter()
	{
		return TryEnterCriticalSection(&internalData->criticalSection) != 0;
	}

	void CriticalSection::Enter()
	{
		EnterCriticalSection(&internalData->criticalSection);
	}

	void CriticalSection::Leave()
	{
		LeaveCriticalSection(&internalData->criticalSection);
	}

	/***********************************************************************
	ReaderWriterLock
	***********************************************************************/

	namespace threading_internal
	{
		struct ReaderWriterLockData
		{
			SRWLOCK			lock;
		};
	}

	ReaderWriterLock::ReaderScope::ReaderScope(ReaderWriterLock& _lock)
		:lock(&_lock)
	{
		lock->EnterReader();
	}

	ReaderWriterLock::ReaderScope::~ReaderScope()
	{
		lock->LeaveReader();
	}

	ReaderWriterLock::WriterScope::WriterScope(ReaderWriterLock& _lock)
		:lock(&_lock)
	{
		lock->EnterWriter();
	}

	ReaderWriterLock::WriterScope::~WriterScope()
	{
		lock->LeaveWriter();
	}

	ReaderWriterLock::ReaderWriterLock()
		:internalData(new threading_internal::ReaderWriterLockData)
	{
		InitializeSRWLock(&internalData->lock);
	}

	ReaderWriterLock::~ReaderWriterLock()
	{
		delete internalData;
	}

	bool ReaderWriterLock::TryEnterReader()
	{
		return TryAcquireSRWLockShared(&internalData->lock) != 0;
	}

	void ReaderWriterLock::EnterReader()
	{
		AcquireSRWLockShared(&internalData->lock);
	}

	void ReaderWriterLock::LeaveReader()
	{
		ReleaseSRWLockShared(&internalData->lock);
	}

	bool ReaderWriterLock::TryEnterWriter()
	{
		return TryAcquireSRWLockExclusive(&internalData->lock) != 0;
	}

	void ReaderWriterLock::EnterWriter()
	{
		AcquireSRWLockExclusive(&internalData->lock);
	}

	void ReaderWriterLock::LeaveWriter()
	{
		ReleaseSRWLockExclusive(&internalData->lock);
	}

	/***********************************************************************
	ConditionVariable
	***********************************************************************/

	namespace threading_internal
	{
		struct ConditionVariableData
		{
			CONDITION_VARIABLE			variable;
		};
	}

	ConditionVariable::ConditionVariable()
		:internalData(new threading_internal::ConditionVariableData)
	{
		InitializeConditionVariable(&internalData->variable);
	}

	ConditionVariable::~ConditionVariable()
	{
		delete internalData;
	}

	bool ConditionVariable::SleepWith(CriticalSection& cs)
	{
		return SleepConditionVariableCS(&internalData->variable, &cs.internalData->criticalSection, INFINITE) != 0;
	}

	bool ConditionVariable::SleepWithForTime(CriticalSection& cs, zint ms)
	{
		return SleepConditionVariableCS(&internalData->variable, &cs.internalData->criticalSection, (DWORD)ms) != 0;
	}

	bool ConditionVariable::SleepWithReader(ReaderWriterLock& lock)
	{
		return SleepConditionVariableSRW(&internalData->variable, &lock.internalData->lock, INFINITE, CONDITION_VARIABLE_LOCKMODE_SHARED) != 0;
	}

	bool ConditionVariable::SleepWithReaderForTime(ReaderWriterLock& lock, zint ms)
	{
		return SleepConditionVariableSRW(&internalData->variable, &lock.internalData->lock, (DWORD)ms, CONDITION_VARIABLE_LOCKMODE_SHARED) != 0;
	}

	bool ConditionVariable::SleepWithWriter(ReaderWriterLock& lock)
	{
		return SleepConditionVariableSRW(&internalData->variable, &lock.internalData->lock, INFINITE, 0) != 0;
	}

	bool ConditionVariable::SleepWithWriterForTime(ReaderWriterLock& lock, zint ms)
	{
		return SleepConditionVariableSRW(&internalData->variable, &lock.internalData->lock, (DWORD)ms, 0) != 0;
	}

	void ConditionVariable::WakeOnePending()
	{
		WakeConditionVariable(&internalData->variable);
	}

	void ConditionVariable::WakeAllPendings()
	{
		WakeAllConditionVariable(&internalData->variable);
	}

	/***********************************************************************
	SpinLock
	***********************************************************************/

	SpinLock::Scope::Scope(SpinLock& _spinLock)
		:spinLock(&_spinLock)
	{
		spinLock->Enter();
	}

	SpinLock::Scope::~Scope()
	{
		spinLock->Leave();
	}

	SpinLock::SpinLock()
		:token(0)
	{
	}

	SpinLock::~SpinLock()
	{
	}

	bool SpinLock::TryEnter()
	{
		return _InterlockedExchange(&token, 1) == 0;
	}

	void SpinLock::Enter()
	{
		while (_InterlockedCompareExchange(&token, 1, 0) != 0)
		{
			while (token != 0) _mm_pause();
		}
	}

	void SpinLock::Leave()
	{
		_InterlockedExchange(&token, 0);
	}
#else
namespace threading_internal
{
	class ProceduredThread :public Thread
	{
	private:
		Thread::ThreadProcedure    procedure;
		void*                      argument;
	protected:
		void                       Run()
		{
			procedure(this, argument);
		}
	public:
		ProceduredThread(Thread::ThreadProcedure _procedure, void* _argument) :procedure(_procedure), argument(_argument)
		{}
	};
};
using namespace threading_internal;

__thread zint Thread::flag = 0;
struct sigaction Thread::suspendsig = { 0 };
struct sigaction Thread::resumesig = { 0 };

void  InteralThreadProc(Thread* thread)
{
	thread->Run();
	if (thread->semaphore.IsCreated())
		thread->semaphore.Post();
}

void* InteralThreadProcWrapper(void* lpParameter)
{
	InteralThreadProc((Thread*)lpParameter);
	return 0;
}

Thread::Thread()
{
	semaphore.Create(0);
	result = 0;
	pthread_create(&pid, NULL, InteralThreadProcWrapper, this) == 0 ? state = ThreadState::Running
		: state = ThreadState::NotStarted;
	if (state != ThreadState::NotStarted)
	{
		pthread_detach(pid);
	}
}

Thread::~Thread()
{}

void    Thread::Sleep(zint seconds)
{
	sleep(seconds);
}

bool    Thread::Pause()
{
	if (pthread_kill(pid, SIGSUSPEND) == 0)
	{
		state = ThreadState::Paused;
		return true;
	}
	return false;
}

bool    Thread::Resume()
{
	if (pthread_kill(pid, SIGRESUME) == 0)
	{
		state = ThreadState::Running;
		return true;
	}
	return false;
}

bool    Thread::IsCreated()
{
	return state != ThreadState::NotStarted;
}

bool    Thread::Wait()
{
	if (semaphore.IsCreated())
	{
		return semaphore.Wait();
	}
	return false;
}



Thread* Thread::Create(ThreadProcedure procedure, void* argument)
{
	if (procedure)
	{
		if (suspendsig.sa_handler == 0 || resumesig.sa_handler == 0)
		{
			suspendsig.sa_handler = Suspendhandler;
			sigaddset(&suspendsig.sa_mask, SIGRESUME);
			sigaction(SIGSUSPEND, &suspendsig, NULL);
			resumesig.sa_handler = Resumehandler;
			sigaddset(&resumesig.sa_mask, SIGSUSPEND);
			sigaction(SIGRESUME, &resumesig, NULL);
		}
		Thread* thread = new ProceduredThread(procedure, argument);
		return thread;
	}
	return 0;
}

void Thread::Suspendhandler(int signum)
{
	flag = 1;
	sigset_t net;
	pthread_sigmask(0, NULL, &net);
	sigdelset(&net, SIGRESUME);
	while (flag)
		sigsuspend(&net);
}

void Thread::Resumehandler(int signum)
{
	flag = 0;
}

Semaphore::Semaphore()
{
	iscreated = false;
}

Semaphore::~Semaphore()
{
	if (isnamed)
	{
		sem_close(&sem);
	}
	else
	{
		sem_destroy(&sem);
	}
}

bool Semaphore::Create(zint value, const std::wstring& name)
{
	isnamed = (name == L"") ? false : true;
	if (isnamed)
	{
		sem_t* tmp = 0;
		tmp = sem_open(wtoa(name).c_str(), O_CREAT, 0666, value);
		if (tmp != 0)
		{
			iscreated = true;
			memcpy(&sem, tmp, sizeof(sem_t));
		}
	}
	else
	{
		sem_init(&sem, 0, value) == 0 ? iscreated = true : iscreated = false;
	}
	return iscreated;
}

bool Semaphore::Open(const std::wstring& name)
{
	if (IsCreated()) return false;
	sem_t* tmp = 0;
	tmp = sem_open(wtoa(name).c_str(), O_EXCL);
	if (tmp != 0)
	{
		iscreated = true;
		memcpy(&sem, tmp, sizeof(sem_t));
		int v;
		sem_getvalue(&sem, &v);
		value = v;
	}
	return iscreated;
}

bool Semaphore::IsCreated()
{
	return iscreated;
}

bool Semaphore::Post()
{
	if (IsCreated())
	{
		return sem_post(&sem) == 0 ? true : false;
	}
	return false;
}

bool Semaphore::Wait()
{
	if (IsCreated())
	{
		return sem_wait(&sem) == 0 ? true : false;
	}
	return false;
}

Mutex::Mutex()
{
	iscreated = false;
}

Mutex::~Mutex()
{
	Release();
}

bool Mutex::Create()
{
	iscreated = (pthread_mutex_init(&mutex, NULL) == 0 && pthread_cond_init(&cond, NULL) == 0) ? true : false;
	return iscreated;
}

bool Mutex::IsCreated()
{
	return iscreated;
}

bool Mutex::Lock()
{
	if (IsCreated())
	{
		return pthread_mutex_lock(&mutex) == 0 ? true : false;
	}
	return false;
}

bool Mutex::UnLock()
{
	if (IsCreated())
	{
		return pthread_mutex_unlock(&mutex) == 0 ? true : false;
	}
	return false;
}

bool Mutex::Wait()
{
	if (IsCreated())
	{
		return pthread_cond_wait(&cond, &mutex) == 0 ? true : false;
	}
	return false;
}

bool Mutex::WaitForTime(zint us)
{
	if (IsCreated())
	{
		struct timespec ts;
		struct timeval  tp;
		gettimeofday(&tp, NULL);
		ts.tv_sec = tp.tv_sec;
		ts.tv_nsec = (tp.tv_usec + us) * 1000;
		return pthread_cond_timedwait(&cond, &mutex, &ts) == 0 ? true : false;
	}
	return false;
}

bool Mutex::WakeUp()
{
	if (IsCreated())
	{
		return pthread_cond_signal(&cond) == 0 ? true : false;
	}
	return false;
}

bool Mutex::WakeUpAll()
{
	if (IsCreated())
	{
		return pthread_cond_broadcast(&cond) == 0 ? true : false;
	}
	return false;
}

void Mutex::Release()
{
	pthread_mutex_destroy(&mutex);
	pthread_cond_destroy(&cond);
}
#endif
};